@* Generator: Template *@
@functions { public dynamic Model { get; set; } }@{
    var dotModule = Model.Module == null ? "" : ("." + Model.Module);
    var moduleDot = Model.Module == null ? "" : (Model.Module + ".");
    var schemaDot = Model.Schema == null ? "" : ("[" + Model.Schema + "].");
     
    Func<string, string, string> jf = (x, y) =>
    {
        if (x.ToLowerInvariant() == y.ToLowerInvariant())
            return y;
        else
            return x + y;
    };
}
namespace @(Model.RootNamespace)@(dotModule).Entities
{
    using Serenity;
    using Serenity.ComponentModel;
    using Serenity.Data;
    using Serenity.Data.Mapping;
    using System;
    using System.ComponentModel;
    using System.IO;

    [ConnectionKey("@Model.ConnectionKey"), TableName("@(String.IsNullOrEmpty(schemaDot) ? Model.Tablename : schemaDot + "[" + Model.Tablename + "]")"), DisplayName("@Model.Title"), InstanceName("@Model.Title"), TwoLevelCached]
    [ReadPermission("@Model.Permission")]
    [ModifyPermission("@Model.Permission")]
    public sealed class @Model.RowClassName : @Model.RowBaseClass, IIdRow@(Model.IsLookup ? ", IDbLookupRow" : "")@(Model.NameField == null ? "" : ", INameRow")
    {@foreach (EntityField x in Model.Fields) {
    var attrs = new List<string>();
    attrs.Add("DisplayName(\"" + x.Title + "\")");

    if (x.Ident != x.Name)
    {
        attrs.Add("Column(\"" + x.Name + "\")");
    }

    if ((x.Size ?? 0) != 0) {
        attrs.Add("Size(" + x.Size + ")");
    }
    if (x.Scale != 0) {
        attrs.Add("Scale(" + x.Scale + ")");
    }
    if (!String.IsNullOrEmpty(x.Flags)) {
        attrs.Add(x.Flags);
    }       
    if (!String.IsNullOrEmpty(x.PKTable)) {
        attrs.Add("ForeignKey(\"" + (string.IsNullOrEmpty(x.PKSchema) ? x.PKTable : ("[" + x.PKSchema + "].[" + x.PKTable + "]")) + "\", \"" + x.PKColumn + "\")");
        attrs.Add("LeftJoin(\"j" + x.ForeignJoinAlias + "\")");
    }
    if (Model.NameField == x.Ident) {
        attrs.Add("QuickSearch");
    }
    if (x.TextualField != null) {
        attrs.Add("TextualField(\"" + x.TextualField + "\")");
    }
    var attrString = String.Join(", ", attrs.ToArray());
<text>
@if (!String.IsNullOrEmpty(attrString)) {
<text>        [@attrString]
</text>}        public @x.DataType@(x.IsValueType ? "?" : "") @x.Ident
        {
            get { return Fields.@(x.Ident)[this]; }
            set { Fields.@(x.Ident)[this] = value; }
        }
</text>}
@foreach (EntityJoin x in Model.Joins){foreach (EntityField y in x.Fields){
<text>
        [DisplayName("@y.Title"), Expression("@("j" + x.Name + ".[" + y.Name + "]")")]
        public @y.DataType@(y.IsValueType ? "?" : "") @(jf(x.Name, y.Ident))
        {
            get { return Fields.@(jf(x.Name, y.Ident))[this]; }
            set { Fields.@(jf(x.Name, y.Ident))[this] = value; }
        }
</text>}}

        IIdField IIdRow.IdField
        {
            get { return Fields.@(Model.Identity); }
        }
@if (Model.NameField != null) {
<text>
        StringField INameRow.NameField
        {
            get { return Fields.@Model.NameField; }
        }
</text>}

        public static readonly RowFields Fields = new RowFields().Init();

        public @(Model.RowClassName)()
            : base(Fields)
        {
        }

        public class RowFields : @(Model.FieldsBaseClass)
        {@foreach (EntityField x in Model.Fields) {
<text>
            public @(x.FieldType)Field @(x.Ident);</text>}
@foreach (EntityJoin x in Model.Joins) {<text>
</text>foreach (EntityField y in x.Fields) {
<text>
            public @(y.FieldType)Field @(jf(x.Name, y.Ident));</text>}}


            public RowFields()
                : base(@(string.IsNullOrEmpty(Model.FieldPrefix) ? "" : ("\"" + Model.FieldPrefix + "\"")))
            {
                LocalTextPrefix = "@(moduleDot)@(Model.ClassName)";
            }
        }
    }
}
